{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <div align='center'> Latex of Product </div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_matrix(M):\n",
    "    for row in M:\n",
    "        for val in row:\n",
    "            print('{:4}'.format(val), end=' ')\n",
    "        print('')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.array([[1,2],\n",
    "              [3,4]])\n",
    "b = np.array([[5,6],\n",
    "              [7,8]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   1    2 \n",
      "   3    4 \n",
      "\n",
      "   5    6 \n",
      "   7    8 \n"
     ]
    }
   ],
   "source": [
    "print_matrix(a)\n",
    "print('')\n",
    "print_matrix(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 向量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 叉乘\n",
    "\n",
    "cross prodcut, latex: $\\times$\n",
    "\n",
    "向量积、矢积、叉乘、外积 \n",
    "\n",
    "求法线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-3,  6, -3])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.cross([1, 2, 3], [4, 5, 6])\n",
    "# 1i + 2j + 3k\n",
    "# 4i + 5j + 6k\n",
    "# [2*6 - 3*5, 3*4 - 1*6, 1*5 - 2*4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-4, -4])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.cross(a, b)\n",
    "# TODO\n",
    "# (1, 2)(7, 8) - (5, 6)(3, 4)\n",
    "# (7, 16) - (15, 24)\n",
    "# (7-15, 16-24) ???"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 点乘 inner product\n",
    "\n",
    "dot product, scalar product, latex: $\\bullet$\n",
    "\n",
    "向量点积 $<\\mathbf u \\mathbf v> = \\mathbf{u}^T \\mathbf v$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot([1, 2, 3], [4, 5, 6])\n",
    "# 1*4 + 2*5 + 3*6 = 32"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   1    2 \n",
      "   3    4 \n",
      "\n",
      "   5    6 \n",
      "   7    8 \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[19, 22],\n",
       "       [43, 50]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print_matrix(a)\n",
    "print('')\n",
    "print_matrix(b)\n",
    "\n",
    "np.dot(a, b)\n",
    "# [[(1,2)(5,7), (1,2)(6,8)], [(3,4)(5,7), (3,4)(6,8)]]\n",
    "# [[19, 22], [43, 50]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 外积 outer product \n",
    "\n",
    "outer product, latex: $\\otimes \\ or\\ \\otimes_{outer}$\n",
    "\n",
    "向量外积 $\\mathbf u \\otimes \\mathbf v = \\mathbf u \\mathbf{v}^T$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 4,  5],\n",
       "       [ 8, 10],\n",
       "       [12, 15]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "u = np.array([1, 2, 3])\n",
    "v = np.array([4, 5])\n",
    "np.outer(u, v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4,  5,  8, 10, 12, 15])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.kron(u, v) # The Kronecker product is a form of vectorization (or flattening) of the outer product. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 矩阵"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 克罗内克积\n",
    "\n",
    "latex: $\\otimes \\ or \\ \\otimes_{kron}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   1    2 \n",
      "   3    4 \n",
      "   5    6 \n",
      "   7    8 \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 5,  6, 10, 12],\n",
       "       [ 7,  8, 14, 16],\n",
       "       [15, 18, 20, 24],\n",
       "       [21, 24, 28, 32]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print_matrix(a)\n",
    "print_matrix(b)\n",
    "np.kron(a, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 哈达玛积\n",
    "\n",
    "Hadamard product, latex:$\\circ$ \n",
    "\n",
    "基本积, element-wise multiply\n",
    "\n",
    "$A*B , A \\circ B, A \\odot B$\n",
    "\n",
    "当矩阵是numpy.ndarray时\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'> <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "print(type(a), type(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2],\n",
       "       [3, 4]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5, 6],\n",
       "       [7, 8]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 5, 12],\n",
       "       [21, 32]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 矩阵乘积\n",
    "\n",
    "matmul product\n",
    "\n",
    "$AB, A \\cdot B, A_{ik}B_{kj}$\n",
    "\n",
    "当矩阵是numpy.matrix时, 都是**\\***号,但结果不同\n",
    "\n",
    "dot, matmul"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.matrix'> <class 'numpy.matrix'>\n"
     ]
    }
   ],
   "source": [
    "c = np.matrix(a)\n",
    "d = np.matrix(b)\n",
    "print(type(c), type(d))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2],\n",
       "       [3, 4]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5, 6],\n",
       "       [7, 8]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[1, 2],\n",
       "        [3, 4]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[5, 6],\n",
       "        [7, 8]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[19, 22],\n",
       "        [43, 50]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c*d\n",
    "# 1*5 + 2*7 | 1*6 + 2*8\n",
    "# 3*5 + 4*7 | 3*6 + 4*8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 5, 12],\n",
       "       [21, 32]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[19, 22],\n",
       "        [43, 50]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(c, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[19, 22],\n",
       "       [43, 50]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[19, 22],\n",
       "        [43, 50]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.matmul(c, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[19, 22],\n",
       "       [43, 50]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.matmul(a, b)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
